const express = require('express');
app.listen(9000, () => console.log("服务已启动"))
const fs = require('fs')
const path = require('path')
const app = express();

/**
 * ======================================== 中间件概述 ========================================
 * 什么是中间件？
 *      中间件是 express 框架的核心
 *      express 应用程序的本质就是一系列中间件函数的调用、简单理解：中间件就是传递给express的一个回调函数
 * 
 * 中间件基本形式
 *      app.请求方式('/请求路径',回调函数 => 中间件) 
 */
app.get('/login', (req, res) => {
    /**
     * req：请求对象
     * res：响应对象
     * next：
     */
    // 1、在中间件中可以执行任意代码，例如获取请求对象、返回响应对象、查询数据库等、判断编写逻辑
    // 2、在中间件可以根据自己的需求结束请求响应
    res.sendFile(__dirname + '/static/index.html')

    // 3、在中间件中执行下一个中间件
})
app.use((req, res, next) => {
    console.log('测试 全局中间件的使用！！！');
    next()
})




/**
 * ======================================== 注册中间件 ========================================
 * 如何注册中间件、中间件都有那种使用方式？
 *     1、express 主要有俩种注册中间件的方式：
 *              全局中间件：app.use()
 *              路由中间件：app.get() \  app.post()  \  app.delete()
 */

/**
 * 全局中间件(基本中间件)
 *      说明：
 *          1、当客户端发起请求时、无论什么请求都会被全局中间件匹配上、执行该中间件中的代码
 *          2、当存在多个中间件时、第二个中间件是否执行取决第一个中间件使用了next() 还是使用 send()
 *             如果使用了next() 表示 继续执行下一个中间件
 *             如果使用了send() 表示 停止响应、返回数据
 *      作用：全局中间件一般用于全局拦截，拦截所有路由，并且在访问路由时进行全局验证
 * 
 */
// 全局中间件的应用场景
//  1、配置静态资源访问中间件
app.use(express.static(__dirname + '/static'))
//  2、配置将访问过的路径及ip保存在日志中
app.use((req, res, next) => {
    fs.appendFileSync(__dirname + '/static/rizhi.log', `${req.url}/${req.ip}\n`)
    next()
})



/**
 * 路径匹配中间件
 *      说明：
 *           当客户端的请求路径与该中间件的路径一致时、就会执行该中间件
 *           不会限制客户端的请求方式
 */
app.use('/home', (req, res, next) => {
    res.send('路径 匹配中间件测试！！！')
})



/**
 * 路径方法匹配中间件
 *       说明：客户端发起的请求必须，请求方法和路径都满足才能该中间件
 *       种类：get() / post() / delete() /
 */
app.get('/my', (req, res) => {
    res.send('路径 + 方法 匹配中间件测试！！！')
})



/**
 * 多中间件注册
 *      说明：一个路径请求匹配多个中间件、每一个中间件的执行取决于上一个中间件是否使用 next
 */
app.post('/user', (req, res, next) => {
    console.log('执行user路径请求中间件-1');
    next()
}, (req, res, next) => {
    console.log('执行user路径请求中间件-2');
    next()
}, (req, res, next) => {
    console.log('执行user路径请求中间件-3');
    next()
}, (req, res, next) => {
    console.log('执行user路径请求中间件-4');
    res.send()
},)




/**
 * 路由中间件
 *      可以理解为拦截局部路由、配置一个路由中间件函数、那个路由方法使用这个中间件就会被约束
 */
// 声明路由中间件、用于验证 /home /admin 请求路径传递的请求参数 code 是否存在、如果没有传就返回 页面错误
// 1、声明中间件函数
const routerMiddleware = (req, res, next) => {
    if (req.query.code) {
        next() // 如果存在就执行对应请求的路径
    } else {
        res.send("<h1>页面错误<h1>")
    }
}
// 2、使用中间件函数、将路由中间件放入被约束的方法中
app.get('/admin', routerMiddleware, (req, res) => {
    res.send("后台首页")
})




// 全请求方式匹配
app.all('/test', (req, res) => {
    console.log("你好 all");
    res.send()
})



/**
 * 404 中间件
 */
app.all('*name', (req, res) => {
    res.send("<h1>404 Not Found</h1>")
});



